package cn.openea.perpartner.rule.web.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.openea.perpartner.rule.compile.DynamicClassLoader;
import cn.openea.perpartner.rule.compile.DynamicRuleCompiler;
import cn.openea.perpartner.rule.util.SpringBeanUtil;
import cn.openea.perpartner.rule.web.entity.SysRule;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.openea.perpartner.rule.web.mapper.SysRuleMapper;
import cn.openea.perpartner.rule.web.service.BaseService;
import cn.openea.perpartner.rule.web.service.ISysRuleService;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * (SysRuleList)表服务实现类
 *
 * @author Weird077
 * @since 2022-09-26 17:00:16
 */
@Service
public class SysRuleServiceImpl extends ServiceImpl<SysRuleMapper, SysRule> implements ISysRuleService {

    @Override
    public List<SysRule> selectList(String searchStr) {
        LambdaQueryWrapper<SysRule> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotBlank(searchStr)) {
            wrapper.and(wrap -> wrap.eq(SysRule::getAppId, searchStr)
                    .or().eq(SysRule::getRuleNum, searchStr)
                    .or().eq(SysRule::getRuleName, searchStr)
                    .or().eq(SysRule::getCreateUserName, searchStr)
                    .or().eq(SysRule::getStatus, searchStr)
            );
        }
        wrapper.orderByDesc(SysRule::getUpdateTime);
        return baseMapper.selectList(wrapper);
    }

    @Override
    public boolean saveAndCompile(SysRule sysRule) {
        boolean success = false;
        try {
            //编译源码
            Map<String, byte[]> bytecode = DynamicRuleCompiler.compileJavaCode(sysRule.getRuleCode());
            DynamicClassLoader classLoader = new DynamicClassLoader(bytecode);
            Class<?> clazz = classLoader.loadClass(bytecode.keySet().iterator().next());
            SpringBeanUtil.register(sysRule.getRuleNum(), clazz);
            if (cn.hutool.core.bean.BeanUtil.isNotEmpty(bytecode)) {
                sysRule.setCompileFlag("1");
                sysRule.setCompileDate(DateUtil.now());
            }
            sysRule.setCompileFlag("1");
            sysRule.setCompileDate(DateUtil.now());
            success = saveOrUpdate(sysRule);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return success;
    }

    @Override
    public String preview(String ruleNum) throws ClassNotFoundException {
        LambdaQueryWrapper<SysRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRule::getRuleNum, ruleNum);
        SysRule sysRule = getOne(wrapper);
        if (cn.hutool.core.bean.BeanUtil.isEmpty(sysRule)) {
            return "class " + ruleNum + " not found";
        }
        if (!SpringBeanUtil.beanIsExists(sysRule.getRuleNum())) {
            Map<String, byte[]> bytecode = DynamicRuleCompiler.compileJavaCode(sysRule.getRuleCode());
            DynamicClassLoader classLoader = new DynamicClassLoader(bytecode);
            Class<?> clazz = classLoader.loadClass(bytecode.keySet().iterator().next());
            SpringBeanUtil.register(sysRule.getRuleNum(), clazz);
            if (cn.hutool.core.bean.BeanUtil.isNotEmpty(bytecode)) {
                sysRule.setCompileFlag("1");
                sysRule.setCompileDate(DateUtil.now());
                saveOrUpdate(sysRule);
            }
        }
        BaseService baseService = SpringUtil.getBean(sysRule.getRuleNum());
        return baseService.run(new HashMap<>());
    }

    @Override
    public boolean checkRuleUnique(String ruleNum) {
        LambdaQueryWrapper<SysRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRule::getRuleNum, ruleNum);
        return count(wrapper) > 0;
    }
    @Override
    public void loadRuleList() {
        try {
            List<SysRule> ruleList = list();
            for (SysRule rule : ruleList) {
                SpringBeanUtil.register(rule.getRuleNum(), rule.getRuleCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

